console.log('myKoa');
/**
 *  明白代理
 *  明白this指向
 */
const http = require('http');
const Stream = require('stream');
const context = require('./context');
const request = require('./request');
const response = require('./response');
class Application {
  constructor() {
    // 我们不能直接把request赋值给context，如果一个应用改了这个值，那其他应用也会改变，因为是引用类型
    this.context = Object.create(context); // 用于继承，既可以继承原本的属性（this.context__proto__），用户也可以扩展新对象，不会影响到原对象
    this.request = Object.create(request);
    this.response = Object.create(response);
  }
  use(fn) {
    // 将use中的函数保存到在实例上

    this.fn = fn;
  }
  createContext(req, res) {
    // 每次请求都创建一个新的上下文，互不干扰
    let ctx = Object.create(this.context);
    // console.log(ctx.__proto__.__proto__);
    let request = Object.create(this.request);
    let response = Object.create(this.response);

    ctx.request = request;
    ctx.req = ctx.request.req = req;
    ctx.response = response;
    ctx.res = ctx.response.res = res;
    return ctx;
  }
  handleRequest(req, res) {
    let ctx = this.createContext(req, res);

    res.statusCode = 404;
    this.fn(ctx); // 內部可能多次設置body的值
    let body = ctx.body;
    if (typeof body === 'string' || Buffer.isBuffer(body)) {
      // 用戶多次設置值採用最後一次
      res.end(body);
    } else if (body instanceof Stream) {
      // 如果是流
      body.pipe(res);
    } else if (body && typeof body === 'object') {
      res.end(JSON.stringify(body));
    } else {
      // 沒有值就404
      res.end('Not Fount');
    }
  }
  listen(...args) {
    let server = http.createServer(this.handleRequest.bind(this));
    server.listen(...args);
  }
}
module.exports = Application;
